package com.koomii.common.util;

import java.util.Date;
import java.util.Locale;


public class IDCardUtil {

	public static String getIdCardTail(char[] chars) {
		if (chars.length < 17) {
			return null;
		}

		int[] rates = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };

		int sum = 0;

		for (int i = 0; i < rates.length; i++) {
			sum += (chars[i] - '0') * rates[i];
		}

		return new char[] { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3',
				'2' }[sum % 11]
				+ "";
	}

	public static String getIdCardTail(String string) {
		return getIdCardTail(string.toCharArray());
	}

	public static void main(String[] args) {
		String id = "X3546700";
		System.out.println(isHongkongIdCard(id));
	}

	/**
	 * 香港身份证号码：<br/>
	 * 身份证号码的「结构」，可以用XYabcdef(z)表示。「X」可能是「空格」或是一个英文字母，「Y」则必定是英文字母。<br/>
	 * 「abcdef」代表一个六位数字，而「z」是作为检码之用，它的可能选择是0, 1, 2, ... , 9,<br/>
	 * A(代表10)。这些代号的背后，都可配上一个编码值。透过编码值，便可找出 9X+8Y+7a+6b+5c+4d+3e+2f+z<br/>
	 * 的总和。该总和特别之处，是必须被11整除。利用这特点，我们便能找出括号内的数字。<br/>
	 * 
	 * 
	 * @param hongkongId
	 * @return
	 */
	public static boolean isHongkongIdCard(final String hongkongId) {
		String idCard = hongkongId.trim().toUpperCase(Locale.US);// 先去除前后空格

		if (idCard.length() == 8) {// 为了方便计算,在前面补上空格
			idCard = " " + idCard;
		}
		if (idCard.length() != 9) {// 长度不合格的去掉
			return false;
		}
		String regex = "^[\\sA-Z][A-Z]\\d{6}[0-9A]$";
		if (!idCard.matches(regex)) {// 用正则去匹配
			return false;
		}
		
		int summary = 0;
		for (int i = 0; i < idCard.length(); i++) {
			int code = codeNumberOfHKID(idCard.charAt(i));
			summary += (9 - i) * code;
		}
		return summary % 11 == 0;
	}

	/**
	 * 香港身份证编码值<br/>
	 * X或Y的编码值:<br/>
	 * 空格 58 I 18 R 27<br/>
	 * A 10 J 19 S 28<br/>
	 * B 11 K 20 T 29<br/>
	 * C 12 L 21 U 30<br/>
	 * D 13 M 22 V 31<br/>
	 * E 14 N 23 W 32<br/>
	 * F 15 O 24 X 33<br/>
	 * G 16 P 25 Y 34<br/>
	 * H 17 Q 26 Z 35<br/>
	 * 
	 * @param c
	 * @return
	 */
	private static int codeNumberOfHKID(char c) {

		if (c == ' ') {
			return 58;
		}

		if (c >= '0' && c <= '9') {
			return c - '0';
		}

		if (c >= 'A' && c <= 'Z') {
			return c - 55;
		}

		return 0;
	}
	/**
	 * 6 14
	 * 362531199105010333
	 * @param idcard
	 * @return
	 */
	public static Date getBirthDay(String idcard){
	    String dateStr = idcard.substring(6, 14);
	    return DateUtil.strToDate("yyyyMMdd",dateStr);
	}
}
